﻿#include "joystickAnalog3d.h"
#include <Windows.h>
#include <QDebug>

JoystickAnalog3D::JoystickAnalog3D(QObject *parent)
    :QThread(parent),
      m_valid(false),
      m_run(true),
      old_xLevel(0),
      old_yLevel(0),
      old_zLevel(0),
      m_signal(false),
      m_xy_signal(false),
      m_z_signal(false),
      m_button_signal(false),
      m_monitor_interval(150)
{
    setLevels(7, 7, 7);
    JOYINFO joyinfo;
    if( joyGetNumDevs() > 0 && joyGetPos(JOYSTICKID1, &joyinfo) != JOYERR_UNPLUGGED )
    {
        m_valid = true;
        qDebug() << "Joystick is NOT Valid!!!";
    }

    for(int i = 0; i < 8; i++)
    {
        m_button[i] = 0;
    }
}

void JoystickAnalog3D::stop()
{
   m_run = 0;
   wait();
}

void JoystickAnalog3D::setLevels(int nX, int nY, int nZ)
{
    if(nX > 0)  m_xStep = 32768 / abs(nX);
    if(nY > 0)  m_yStep = 32768 / abs(nY);
    if(nZ > 0)  m_zStep = 32768 / abs(nZ);
}

void JoystickAnalog3D::run()
{
    JOYINFOEX joyinfoex;
    joyinfoex.dwSize = sizeof(JOYINFOEX);
    joyinfoex.dwFlags = JOY_RETURNALL;
    while(m_valid && m_run)
    {
        if(joyGetPosEx(JOYSTICKID1, &joyinfoex) == JOYERR_NOERROR && m_signal)
        {
            if(m_xy_signal)
            {
                AxisX_StateMachine(joyinfoex.dwXpos);
                AxisY_StateMachine(joyinfoex.dwYpos);
            }
            if(m_z_signal)
            {
                AxisZ_StateMachine(joyinfoex.dwZpos);
            }
            if(m_button_signal)
            {
                Button_StateMachine(joyinfoex.dwButtons);
            }
        }

        msleep(m_monitor_interval);
    }
}

void JoystickAnalog3D::setMonitorInterval(int interval)
{
    m_monitor_interval = qBound(20, interval, 10000);
}

void JoystickAnalog3D::AxisX_StateMachine(int xPos)
{
    int level = xPos / m_xStep;
    if(level != old_xLevel)
    {
        old_xLevel = level;
        emit Joy_xMove(level);
    }
}
void JoystickAnalog3D::AxisY_StateMachine(int yPos)
{
    int level = yPos / m_yStep;
    if(level != old_yLevel)
    {
        old_yLevel = level;
        emit Joy_yMove(level);
    }
}
void JoystickAnalog3D::AxisZ_StateMachine(int zPos)
{
    int level = zPos / m_zStep;
    if(level != old_zLevel)
    {
        old_zLevel = level;
        emit Joy_zMove(level);
    }
}


void JoystickAnalog3D::Button_StateMachine(int button)
{
    const int mask[8] = {1, 2, 4, 8, 16, 32, 64, 128};
    for(int i = 0; i < 8; i++)
    {
        int n = button & mask[i];
        if(n ^ m_button[i]) // 如果当前 button 与以前的 button 不同
        {
            m_button[i] = n;
            if(!m_signal || !m_button_signal) continue;
            if( n )
            {
                qDebug() << "Joy_Button" << i+1 << "Pressed()";
                switch (i + 1)
                {
                case 1:
                    emit Joy_Button1Pressed();
                    break;
                case 2:
                    emit Joy_Button2Pressed();
                    break;
                case 3:
                    emit Joy_Button3Pressed();
                    break;
                case 4:
                    emit Joy_Button4Pressed();
                    break;
                case 5:
                    emit Joy_Button5Pressed();
                    break;
                case 6:
                    emit Joy_Button6Pressed();
                    break;
                case 7:
                    emit Joy_Button7Pressed();
                    break;
                case 8:
                    emit Joy_Button8Pressed();
                    break;
                default:
                    break;
                }
            }
            else
            {
                qDebug() << "Joy_Button" << i+1 << "Released()";
                switch (i + 1)
                {
                case 1:
                    emit Joy_Button1Released();
                    break;
                case 2:
                    emit Joy_Button2Released();
                    break;
                case 3:
                    emit Joy_Button3Released();
                    break;
                case 4:
                    emit Joy_Button4Released();
                    break;
                case 5:
                    emit Joy_Button5Released();
                    break;
                case 6:
                    emit Joy_Button6Released();
                    break;
                case 7:
                    emit Joy_Button7Released();
                    break;
                case 8:
                    emit Joy_Button8Released();
                    break;
                default:
                    break;
                }
            }
        }
    }
}


